import { dataSource } from '../config/database';
import { AdminEntity } from '../entity/Admin.entity';
import { md5 } from 'js-md5';
import { decodeToken, generateToken } from '../jwt/jwtService';
import { getRedis, setRedis } from '../redis/Redis';
import Result from '../vo/result';
import { ResultCode, ResultCodeMessages } from '../enums/resultCode';
import { sendMail, smtp } from '../config/mailerConfig';
import { getCode } from '../utits/utits';

const tableRepository = dataSource.getRepository(AdminEntity);

export const getAdminByIdService = async (adminId: number) => {
  const admin = await tableRepository.findOneBy({ adminId: adminId });
  if (!admin) {
    return Result.fail(ResultCode.USER_NOT_EXIST, ResultCodeMessages[ResultCode.USER_NOT_EXIST]);
  }
  return Result.success(admin);
};

export const adminLoginService = async (username: string, password: string) => {
  const admin = await tableRepository.findOneBy({ username: username });
  if (admin && admin.password === md5(password)) {
    const token = generateToken({ userId: String(admin.adminId).padStart(8, '0') });
    token && await setRedis(`token_admin_login_${String(admin.adminId).padStart(8, '0')}`, token, 60 * 60 * 24 * 7);
    return Result.success(token, '登录成功');
  }
  return Result.fail(ResultCode.LOGIN_ERROR, ResultCodeMessages[ResultCode.LOGIN_ERROR]);
};

export const AdminPasswordUpdateService = async (ctx) => {
  const token = ctx.headers.authorization;
  const { password } = ctx.request.body;
  const decoded = decodeToken(token.replace('Bearer ', ''));
  const admin = await tableRepository.findOneBy({ adminId: decoded.adminId });
  if (!admin || admin.password !== md5(password)) {
    return Result.fail(ResultCode.LOGIN_ERROR, ResultCodeMessages[ResultCode.LOGIN_ERROR]);
  }
  return Result.success('修改成功');
};

export const AdminTokenCheck = async (token) => {
  //查询这个token是否在redis中
  try {
    const decoded = decodeToken(token.replace('Bearer ', ''));
    const admin = await tableRepository.findOneBy({ adminId: decoded.adminId });
    let redisToken = await getRedis(`token_admin_login_${String(admin.adminId).padStart(8, '0')}`);
    if (redisToken) return Result.success();
    return Result.fail(ResultCode.TOKEN_ERROR, ResultCodeMessages[ResultCode.TOKEN_ERROR]);
  } catch (e) {
    return Result.fail(ResultCode.TOKEN_ERROR, ResultCodeMessages[ResultCode.TOKEN_ERROR]);
  }
};

export const adminEmailVerify = async (email: string) => {
  const admin = await tableRepository.findOneBy({ email: email });
  if (admin) {
    return Result.fail(ResultCode.EMAIL_EXIST, ResultCodeMessages[ResultCode.EMAIL_EXIST]);
  }
  //防止频繁发送邮件
  const redisCode = await getRedis(email);
  if (redisCode) {
    return Result.fail(ResultCode.EMAIL_EXIST, '请勿频繁发送邮件');
  }
  await setRedis(email, '1', 60);


  const from = '认证邮件' + '<' + smtp.getUser() + '>';
  const code = getCode();
  await sendMail(from, email, '邮箱验证码', '您的验证码是：' + code + '，请在5分钟内输入');
  await setRedis(email + '_' + code, code, 60 * 5);
  return Result.success(null, '邮件发送成功');
};

export const AdminRegisterService = async (username: string, password: string, email: string, code: string) => {
  const redisCode = await getRedis(email + '_' + code);
  if (!redisCode) {
    return Result.fail(ResultCode.FAIL, '验证码错误或已过期');
  }
  const admin = await tableRepository.findOneBy({ email: email })
    || await tableRepository.findOneBy({ username: username });
  if (admin) {
    return Result.fail(ResultCode.EMAIL_EXIST, ResultCodeMessages[ResultCode.EMAIL_EXIST]);
  }
  const newAdmin = new AdminEntity();
  newAdmin.username = username;
  newAdmin.password = md5(password);
  newAdmin.email = email;
  await tableRepository.save(newAdmin);
  const res = await adminLoginService(username, password);
  if (res.code === '1') {
    return Result.success(res.data, '注册成功');
  }
  return Result.fail(ResultCode.FAIL, '注册失败');
};
